package translation;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;

public class NetSystem {

	
	LinkedList<Net> nets;
	//Circuit var is needed so single nets can determine their component parts
	Circuit circuit;
	
	/**
	 * reads a given netlist and inserts net objects into the nets var
	 * @param eagle the netlist file to be read
	 * @throws IOException
	 */
	public void readNetList(File eagle) throws IOException {
		BufferedReader in = null;
		LinkedList<String> text = new LinkedList<String>();
		
		try {
			in = new BufferedReader(new FileReader(eagle));
			String s;
            while ((s = in.readLine()) != null) {
            	text.add(s);
            }
            interpretNetList(text);
		} finally {
			if (in != null) {
				in.close();
			}
		}
	}
	
	/**
	 * reads a dissected eagle netlist and adds the constituent nets to its nets var
	 * @param text a netlist file dissected into a list of one-line strings
	 */
	private void interpretNetList(LinkedList<String> text) {
		int firstPartLine = 0;
		for (int i = 0; i<text.size(); i++) {
			String nonspace = text.get(i).replaceAll(" ", "");
			if (nonspace.equals("NetPartPadPinSheet")) {
				firstPartLine = i+2;
				break;
			}
		}
		LinkedList <String> singleNet = new LinkedList<String>();
		for (int i = firstPartLine; i <text.size(); i++) {
			if (text.get(i).equals("") == false) {
				if (text.get(i).startsWith(" ") == false && singleNet.isEmpty() == false) {
					addNet(singleNet);
					singleNet.clear();
				}
				singleNet.add(text.get(i));
			}
		}
		if (singleNet.isEmpty() == false && singleNet.get(0).equals("") == false) {

			addNet(singleNet);
		}
	}
	
	
	/**
	 * adds a net to the list of nets held by the NetSystem
	 * @param netDesc a description of the net as a number of lines of text as given by the eagle file
	 */
	private void addNet(LinkedList <String> netDesc) {
		String firstLine = netDesc.get(0);
		while (firstLine.contains("  ")) {
			firstLine = firstLine.replace("  ", " ");			
		}
		String[] firstStrippedLine = firstLine.split(" ");
		String netName = firstStrippedLine[0];
		LinkedList<String> parts = new LinkedList<String>();
		LinkedList<String> pads = new LinkedList <String>();
		LinkedList<String> pins = new LinkedList <String>();
		parts.add(firstStrippedLine[1]);
		pads.add(firstStrippedLine[2]);
		pins.add(firstStrippedLine[3]);
		
		for (int i = 1; i < netDesc.size(); i++) {
			String line = netDesc.get(i).replace("  ", " ");
			while (line.contains("  ")) {
				line = line.replace("  ", " ");
			}
			String[] strippedLine = line.split(" ");
			parts.add(strippedLine[1]);
			pads.add(strippedLine[2]);
			pins.add(strippedLine[3]);
		}

		nets.add(new Net(netName, parts, pads, pins, this));
	}
	
	
	/**
	 * writes the net to a modelica file
	 * @param out a BufferedWriter to write to
	 * @throws IOException
	 */
	public void writeNetList(BufferedWriter out) throws IOException {
		for (Net n: nets){
			out.write("// Net " + n.getName() + "\n");
			for (int i = 0; i < n.getConnectors().size()-1; i++) {
				out.write("connect(" + n.getParts(i).getName() + "." + n.getConnectors(i) + ", " + n.getParts(i+1).getName() + "." + n.getConnectors(i+1) +");\n");
			}
		}
	}
	

	public LinkedList<Net> getNets() {
		return nets;
	}

	public Circuit getCircuit() {
		return circuit;
	}
	
	/**
	 * @param args
	 */
//	public static void main(String[] args) {
//		testRun();
//	}
	
	/**
	 * Does no longer work since net system needs a part system for connector purposes
	 */
//	private static void testRun() {
//		NetSystem sys = new NetSystem(null);
//		try {
//			sys.readNetList(new File ("D:\\Bachelor\\EAGLE\\Beispiele\\Test\\stuff2Net"));
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//	}

	public NetSystem(Circuit circuit) {
		super();
		this.circuit = circuit;
		this.nets = new LinkedList<Net>();
	}
	
	
	
}
